# SPDX-License-Identifier: Apache-2.0

include_guard(GLOBAL)

add_library(common_interface INTERFACE)

# Common toolchain-agnostic assembly flags
target_compile_options(common_interface INTERFACE $<$<COMPILE_LANGUAGE:ASM>:-D__ASSEMBLY__>)

function(common_cc_options item)
  target_cc_options(common_interface INTERFACE ${item} ${ARGN})
endfunction()

target_compile_options(common_interface INTERFACE "SHELL: -imacros ${KCONFIG_H}")

target_include_directories(common_interface SYSTEM INTERFACE ${NOSTDINC})
target_include_directories(common_interface INTERFACE ${APPLICATION_BINARY_DIR}/include)

common_cc_options(-fdiagnostics-color=always)

# Some of the diagnostics controlled by this flag are enabled
# Controls -Wmisleading-indentation, -Wmost, -Wparentheses, -Wswitch, -Wswitch-bool.
common_cc_options(-Wall)

# Some of the diagnostics controlled by this flag are enabled.
# controls:
# -Wdeprecated-copy, -Wempty-init-stmt, -Wfuse-ld-path,
# -Wignored-qualifiers, -Winitializer-overrides, -Wmissing-field-initializers,
# -Wmissing-method-return-type, -Wnull-pointer-arithmetic,
# -Wnull-pointer-subtraction, -Wsemicolon-before-method-body,
# -Wsign-compare, -Wstring-concatenation, -Wunused-but-set-parameter,
# -Wunused-parameter.
common_cc_options(-Wextra)

common_cc_options(-Werror)

common_cc_options(-std=gnu11)
common_cc_options(-nostdinc)

# Enable optimizations based on the strict definition of an enum’s value range.
common_cc_options(-fno-strict-aliasing)

# Place uninitialized global variables in a common block.
common_cc_options(-fno-common)

# We use -fwrapv to tell the compiler that we require a C dialect where
# left shift of signed integers is well defined and has the expected
# 2s-complement style results. (Both clang and gcc agree that it
# provides these semantics.)
common_cc_options(-fwrapv)

common_cc_options(-Wwrite-strings)

# Warn if a global function is defined without a previous prototype declaration.
common_cc_options(-Wmissing-prototypes)

# Warn if a function is declared or defined without specifying the argument types.
common_cc_options(-Wstrict-prototypes)

target_compile_definitions(common_interface INTERFACE _GNU_SOURCE _XOPEN_SOURCE=700 _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE)

common_cc_options(
  -Wold-style-declaration -Wold-style-definition -Wtype-limits
  -Wformat-security -Wformat-y2k -Winit-self -Wempty-body -Wendif-labels
  -Wexpansion-to-defined
)

# -Wimplicit-fallthrough=2 doesn’t recognize any comments as
# fallthrough comments, only attributes disable the warning.
common_cc_options(-Wimplicit-fallthrough=2)

# Warn about string constants that are longer than the “minimum maximum”
# length specified in the C standard.
common_cc_options(-Woverlength-strings)

# Warn for pointer argument passing or assignment with different signedness.
common_cc_options(-Wpointer-sign)

# The compiler gives a warning when reordering code.
common_cc_options(-Wreorder)

# Warn whenever a local variable or type declaration shadows another variable,
# parameter, type, class member (in C++), or instance variable (in Objective-C)
# or whenever a built-in function is shadowed.
common_cc_options(-Wshadow)

# Issue a warning for any floating constant that does not have a suffix.
common_cc_options(-Wunsuffixed-float-constants)

# Warn if an object with automatic or allocated storage duration
# is used without having been initialized.
# "-Wmaybe-uninitialized" is issued for ordinary functions.
common_cc_options(-Wuninitialized)

# For an object with automatic or allocated storage duration,
# if there exists a path from the function entry to a use of
# the object that is initialized, but there exist some other paths
# for which the object is not initialized, the compiler emits a warning
# if it cannot prove the uninitialized paths are not executed at run time.
common_cc_options(-Wmaybe-uninitialized)

# -Wunused-value, -Wunused-variable, -Wunused-label, -Wunused-but-set-parameter
# -Wunused-const-variable, -Wunused-function, -Wunused-but-set-variable ...
# All the above -Wunused options combined.
common_cc_options(-Wunused)

# Warn if a register variable is declared volatile.
common_cc_options(-Wvolatile-register-var)

# Warn if a function that is declared as inline cannot be inlined.
common_cc_options(-Winline)

# Warn if code will never be executed.
common_cc_options(-Wunreachable-code)

# Warn whenever a function is defined with a return type that defaults to int.
common_cc_options(-Wreturn-type)

# Check calls to printf and scanf, etc., to make sure that the arguments
# supplied have types appropriate to the format string specified,
# and that the conversions specified in the format string make sense.
common_cc_options(-Wformat)

# If -Wformat is specified, also warn if the format string is not a string
# literal and so cannot be checked, unless the format function takes
# its format arguments as a va_list.
common_cc_options(-Wformat-nonliteral -Wvarargs)

# Function cannot return qualified void type A.
common_cc_options(-Wqualified-void-return-type)

# Some of the diagnostics controlled by this flag are enabled by default.
common_cc_options(-Wcalled-once-parameter)

# Warn when a declaration is found after a statement in a block.
common_cc_options(-Wdeclaration-after-statement)

# Conflicting parameter types in implementation.
common_cc_options(-Wmismatched-parameter-types)

# No previous extern declaration for non-static variable A.
common_cc_options(-Wmissing-variable-declarations)

# Warn about function pointers that might be candidates for format attributes.
common_cc_options(-Wmissing-format-attribute)

# Warn if a global function is defined without a previous prototype declaration.
common_cc_options(-Wmissing-braces)

# This diagnostic flag exists for GCC compatibility, and has no effect in Clang.
common_cc_options(-Wstrict-overflow)

# Warn when macros __TIME__, __DATE__ or __TIMESTAMP__ are encountered as
# they might prevent bit-wise-identical reproducible compilations.
common_cc_options(-Wdate-time)

# Do warn when there is a conversion between pointers that have incompatible types.
common_cc_options(-Wincompatible-pointer-types)

# This option controls warnings when a declaration does not specify a type.
common_cc_options(-Wimplicit-int -Wimplicit-function)

# Now, warning_extended has initializer overrides prior initialization of this subobject
# To remove it for kernel.
common_cc_options(-Wno-initializer-overrides)

# Disable "-Wunused-parameter" diagnostic.
common_cc_options(-Wno-unused-parameter)

# Disable warn Some of the diagnostics controlled for GNU extension.
common_cc_options(-Wno-gnu)

# Disable extension used warn.
common_cc_options(-Wno-language-extension-token)

# Disable warn for C99 feature.
common_cc_options(-Wno-variadic-macros)

common_cc_options(-Wno-format-truncation)

# Disable Warn about anything that depends on the “size of” a function type or of void.
common_cc_options(-Wno-pointer-arith)

# Disable Warn if a variable-length array is used in the code. :)
common_cc_options(-Wno-vla)

# Defines char as signed.
common_cc_options(-fsigned-char)

# Force wchar_t to be a short unsigned int.
common_cc_options(-fshort-wchar)

# Defines the bitfield as unsigned.
common_cc_options(-fno-unsigned-bitfields)

if(CONFIG_CC_OPTIMIZE_FOR_SIZE)
  target_cc_option_fallback(common_interface INTERFACE -Oz -Os)
else()
  common_cc_options(-O2)
endif()

if(CONFIG_DEBUG_INFO)
  if(CONFIG_DEBUG_INFO_SPLIT)
    target_cc_option_fallback(common_interface INTERFACE -gsplit-dwarf -g)
  else()
    common_cc_options(-g)
  endif()
endif()

if(CONFIG_DEBUG_INFO_DWARF4)
  common_cc_options(-gdwarf-4)
endif()

if(CONFIG_DEBUG_INFO_REDUCED)
  common_cc_options(-femit-struct-debug-baseonly -fno-var-tracking)
endif()

target_compile_definitions_ifdef(CONFIG_RELEASE_SEMINIX common_interface INTERFACE NDEBUG)
